package com.me.supermario.screens;


import java.util.Iterator;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTile;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
import com.badlogic.gdx.maps.tiled.tiles.AnimatedTiledMapTile;
import com.badlogic.gdx.maps.tiled.tiles.StaticTiledMapTile;
import com.badlogic.gdx.utils.Array;
import com.me.supermario.Time;
import com.me.supermario.entities.*;


public class Play implements Screen {

	//VARIABILI IMPORTANTI
	private TiledMap map;
	private OrthogonalTiledMapRenderer renderer;
	private OrthographicCamera camera;
	private Music bgm;
	private Music overworldBGM = Gdx.audio.newMusic(Gdx.files.internal("com/me/sounds/overworld.mp3"));
	private Time timer = new Time(200);

	//SPRITES
	private Player player;
	private TextureAtlas playerAtlas;
	private Goomba goomba, goomba2;
	private Koopa koopa;
	private OneUP fungo;
	private FireFlower fireFlower, fireFlower2;
	private Super mush;
	private Super funghetto;
	private Guscio guscio;

	//ARRAY
	private static Array<Goomba> goombas= new Array<Goomba> ();
	private static Array<OneUP> funghi = new Array<OneUP>();
	private static Array<Mushroom> mushes = new Array<Mushroom>();
	private static Array<Super> supers = new Array<Super>();
	private static Array<FireFlower> fireFlowers = new Array<FireFlower>();
	private static Array<Guscio> gusci = new Array<Guscio> ();
	private static Array<Koopa> koopas = new Array<Koopa>();

	//VARIABILI BOOLEANE
	private boolean primaVolta = true, avviatoFungo = true, disappear = false, disappear2 = false;
	private boolean mushAvviato = true;
	private boolean guscioAvviato = false;
	private boolean isPaused = false;

	//VARIABILI INTERE
	private int [] background = new int [] {1}, foreground = new int [] {2}, sfondo = new int [] {0};
	private int indiceFuoco;
	private int timeAtPause; 
	
	//STATISTICHE LIVELLO
	private TextureRegion coin = new TextureRegion( new Texture("com/me/img/coin.png"));
	private TextureRegion life = new TextureRegion( new Texture("com/me/img/vite.png"));
	private TextureRegion time = new TextureRegion( new Texture("com/me/img/clock.png"));
	private BitmapFont font = new BitmapFont( Gdx.files.internal("com/badlogic/gdx/utils/arial-15.fnt"),
			Gdx.files.classpath("com/badlogic/gdx/utils/arial-15.png"), false, true);

	//Fireball -DEPRECATED?-
	private static Array<Fireball> fireballs = new Array<Fireball>(3);

	

	//------------------------------------------------------------------------------------------//

	@Override
	public void render(float delta) {
		if (!isPaused){
			Gdx.gl.glClearColor(0, 0, 0, 1);
			Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

			renderer.setView(camera);
			renderer.render();

			if( player.getX()<=149 && player.getY()<200 )
				camera.position.set((float)149, player.getHeight() /2 + 93, 0);
			else  if( player.getX()>149 )
				if( player.getY()<=130)
					camera.position.set(player.getX() + player.getWidth() /2, player.getHeight() /2 + 93, 0);
				else
					camera.position.set(player.getX() + player.getWidth()/2, player.getY()+ player.getHeight()/+60,0);
			if( player.getX()>=640 && player.getY()<120 )
				camera.position.set((float)640, player.getHeight()/2+93 ,0);
			else if( player.getX()>640 && player.getY()>=120 )
				camera.position.set((float)640,player.getY()+player.getHeight()/2+60,0);
			camera.update();

			renderer.render(sfondo);
			renderer.render (background);	
			renderer.getSpriteBatch().begin();

			//GOOMBA NUMERO 1
			if (! goomba.getDeadState() || !disappear){
				goomba.draw (renderer.getSpriteBatch());
			}//goomba ancora vivo
			if (goomba.getDeadState()){
				if (goomba.getTime().getTime()<0){
					goomba.setPosition(-2 * goomba.getCollisionLayer().getTileWidth(), -2 *player.getCollisionLayer().getTileHeight());
					disappear = true;
				}
			}// gomba morto

			//GOOMBA NUMERO 2
			if (! goomba2.getDeadState() || !disappear2){
				goomba2.draw (renderer.getSpriteBatch());
			}//goomba ancora vivo
			if (goomba2.getDeadState()){
				if (goomba2.getTime().getTime()<0){
					goomba2.setPosition(-2 * goomba2.getCollisionLayer().getTileWidth(), -2 *goomba.getCollisionLayer().getTileHeight());
					disappear2 = true;
				}
			}//goomba morto
			
			//KOOPA
			if(! koopa.getDeadState() ){
				koopa.draw(renderer.getSpriteBatch());
			}else
			if (! guscio.getDeadState() ) {
				if( !guscioAvviato ) {
					guscio.setPosition(koopa.getX(), koopa.getY());
					guscioAvviato = true;
				}
				guscio.draw(renderer.getSpriteBatch());
			}
			//FUNGO 1UP
			if (! fungo.getDeadState()){
				fungo.draw(renderer.getSpriteBatch());
			}//fungo non preso
			
			//FUNGO MUSH
			if( !mush.getDeadState()){
				mush.draw(renderer.getSpriteBatch());
			}
			
			//FUNGO FUNGHETTO
//			if( funghetto==null && player.collidesTop() ){
//				System.out.println("inizializzo");
//				//funghetto
//				funghetto = new Super((TiledMapTileLayer)(map.getLayers().get(1)));
//				funghetto.setPosition(8*16, 80);
//				supers.add(funghetto);
//			}
//			if( funghetto!=null && !funghetto.getDeadState() ){
//				funghetto.draw(renderer.getSpriteBatch());
//			}

			//FIREFLOWER 1 & 2
			if (! fireFlower.getDeadState()){
				fireFlower.draw(renderer.getSpriteBatch());
			}//flower1 non preso
			if (! fireFlower2.getDeadState ()){
				fireFlower2.draw(renderer.getSpriteBatch());
			}//flower2 non preso

			if (player.getDeadState()){
				bgm.stop();
				Time MDTime = player.getMarioDeathTime();
				if (MDTime.getTime()<0){
					bgm = overworldBGM;
					bgm.setLooping(true);
					bgm.play();
					player.setDeadState(false);
					player.decreaseLife();
					try {
						player.setMarioDeathTime();
					} catch (InterruptedException e) {}
					//setposition
					//TODO(CHECKPOINT)
					//if (checkpoint) { player.setPosition(checkX, checkY) }
					//else {
					player.setPosition(10 * player.getCollisionLayer().getTileWidth(), 3 * player.getCollisionLayer().getTileHeight());

				}
			}
			if (player.getInvulnerability()){
				/*System.out.println("sei invulnerabile!");
				System.out.println("" +player.getInvulnerableTime().isAlive());*/
				//non so il perche' della prossima istruzione. Senza di questa, se cadi, poi prendi un fire
				//flower e poi ti fai colpire, resti invulnerabile per sempre. =S
				if (!player.getInvulnerableTime().isAlive()){
					/*System.out.println("setto");*/
					player.createInvulnerableTime();
				}

				if (player.getInvulnerableTime().getTime()<0){
					player.setInvulnerability(false);
					if(!player.getFireMario() && !player.getBigMario()){
					player.setNormalAnimation();
					}
					player.setInvulnerableTime();
				}
			}

			/*	if (player.getSpara() && !fireball.getDeadState() ){
			fireball.draw(renderer.getSpriteBatch());	
		}*/

			for( int i =0;i<3;i++ )
				if (fireballs.get(i)!=null && player.getSpara() && !fireballs.get(i).getDeadState() ){
					fireballs.get(i).draw(renderer.getSpriteBatch());
				}	

			if (!player.getDeadState()){
				player.draw (renderer.getSpriteBatch());
			}

			renderer.getSpriteBatch().end();		
			renderer.render(foreground);
	
			renderer.getSpriteBatch().begin();
			
			renderer.getSpriteBatch().draw(coin, camera.position.x+100, camera.position.y+77, 0, 0, 12, 12, 1,1, 0);
			renderer.getSpriteBatch().draw(life, camera.position.x-140, camera.position.y+77, 0, 0, 12, 12, 1,1, 0);
			renderer.getSpriteBatch().draw(time, camera.position.x, camera.position.y+77, 0, 0, 12, 12, 1,1, 0);
			font.draw(renderer.getSpriteBatch(), ""+player.getCoin(), camera.position.x+120, camera.position.y+ 90);
			font.draw(renderer.getSpriteBatch(), ""+player.getLife(), camera.position.x-130, camera.position.y+ 90);
			//TODO VELOCIZZA CANZONE ALLO SCADERE DEL TEMPO
			//if (timer.getTime()<30){
			//	bgm = Gdx.audio.newMusic(Gdx.files.internal("com/me/sounds/overworldFAST.mp3"));
			//}
			if( timer.getTime()<0 ){
				player.timedOut();
				timer.setTime(200);
			}
			font.draw(renderer.getSpriteBatch(), ""+timer.getTime(), camera.position.x+20, camera.position.y+ 90);
			//System.out.println("camera x: "+camera.position.x+" camera y: "+camera.position.y );
			renderer.getSpriteBatch().end();
			
		}//if(!isPaused)
	}//render

	@Override
	public void resize(int width, int height) {
		pause();
		camera.viewportWidth = 300;
		camera.viewportHeight = 200;
		camera.update();
		resume();
	}//resize

	@Override
	public void show() {
		TmxMapLoader loader = new TmxMapLoader ();
		map = loader.load("com/me/maps/Mario.tmx");

		inizializzaFuoco();

		renderer = new OrthogonalTiledMapRenderer(map);
		Gdx.gl.glLineWidth(3);

		camera = new OrthographicCamera();
		timer.start();
	
		
		//mario
		playerAtlas = new TextureAtlas("com/me/img/player.pack");
		Animation still, left, right;
		still = new Animation(1/2f, playerAtlas.findRegions("stilldx"));
		left = new Animation (1/6f, playerAtlas.findRegions("left"));
		right = new Animation (1/6f, playerAtlas.findRegions("right"));;
		still.setPlayMode(Animation.LOOP);
		left.setPlayMode(Animation.LOOP);
		right.setPlayMode(Animation.LOOP);

		//player = new Player (new Sprite(new Texture("img/player.png")), (TiledMapTileLayer) (map.getLayers().get(0)));
		player = new Player (still,left,right,(TiledMapTileLayer)(map.getLayers().get(1)),this);
		player.setPosition(10 * player.getCollisionLayer().getTileWidth(), 13 * player.getCollisionLayer().getTileHeight());

		player.getInvulnerableTime().start();

		//goomba

		goomba = new Goomba ((TiledMapTileLayer)(map.getLayers().get(1)));
		goomba.setPosition(12 * goomba.getCollisionLayer().getTileWidth(), 6*goomba.getCollisionLayer().getTileHeight());
		goomba2 = new Goomba ((TiledMapTileLayer)(map.getLayers().get(1)));
		goomba2.setPosition(17* goomba2.getCollisionLayer().getTileWidth(), 6*goomba2.getCollisionLayer().getTileHeight());

		//if (primaVolta){
		goombas.add(goomba);
		goombas.add(goomba2);
		riproduciBGM();
		primaVolta = false;
		//}
		
		
		//koopa
		koopa = new Koopa( (TiledMapTileLayer)map.getLayers().get(1));
		koopa.setPosition(12 * koopa.getCollisionLayer().getTileWidth(),  6*koopa.getCollisionLayer().getTileHeight());
		koopas.add(koopa);

		guscio = new Guscio ( (TiledMapTileLayer)(map.getLayers().get(1)), player );
		guscio.setPosition(22*guscio.getCollisionLayer().getTileWidth(), 4*guscio.getCollisionLayer().getTileHeight());
		gusci.add(guscio);
		//1up
		fungo = new OneUP ((TiledMapTileLayer) (map.getLayers().get(1)));
		fungo.setPosition(15 * fungo.getCollisionLayer().getTileWidth(), 4*fungo.getCollisionLayer().getTileHeight());
		if( avviatoFungo ){
			funghi.add(fungo);
			avviatoFungo = false;
		}
		
		//mushroom
		mush = new Super((TiledMapTileLayer)(map.getLayers().get(1)));
		mush.setPosition(20 * fungo.getCollisionLayer().getTileWidth(), 4*fungo.getCollisionLayer().getTileHeight());
		if( mushAvviato ){
			supers.add(mush);
			mushAvviato = false;
		}
		
		//fireFlower
		fireFlower = new FireFlower ((TiledMapTileLayer)(map.getLayers().get(1)));
		fireFlower.setPosition(15 * fireFlower.getCollisionLayer().getTileWidth(), 4*fireFlower.getCollisionLayer().getTileHeight());

		fireFlower2 = new FireFlower ((TiledMapTileLayer)(map.getLayers().get(1)));
		fireFlower2.setPosition(17 * fireFlower2.getCollisionLayer().getTileWidth(), 4*fireFlower2.getCollisionLayer().getTileHeight());
		fireFlowers.add(fireFlower);
		fireFlowers.add(fireFlower2);

	
		/*fireball = new Fireball (fireLeft, fireRight, (TiledMapTileLayer)(map.getLayers().get(1)), player);
		if (fireNonAncoraDisegnata){
			fireball.setPosition(10 * player.getX(), 3 * player.getY());
			fireNonAncoraDisegnata = false;
		}
		fireballs.add(fireball);*/

		Gdx.input.setInputProcessor(player);

		//TILES ANIMATI

		//frames 
		Array<StaticTiledMapTile> surpriseTiles = new Array<StaticTiledMapTile> (4);
		Array<StaticTiledMapTile> coinTiles = new Array<StaticTiledMapTile> (4);
		Array<StaticTiledMapTile> bloccTiles = new Array<StaticTiledMapTile> (4);

		//prendi i tile giusti
		Iterator <TiledMapTile> tiles = map.getTileSets().getTileSet("mapsheet").iterator();

		while (tiles.hasNext()){
			TiledMapTile tile = tiles.next();
			if (tile.getProperties().containsKey("animation") && tile.getProperties().get("animation", String.class).equals("surprise"))
				surpriseTiles.add((StaticTiledMapTile)tile);
		}
		tiles = map.getTileSets().getTileSet("mapsheet").iterator();
		while (tiles.hasNext()){
			TiledMapTile tile = tiles.next();
			if (tile.getProperties().containsKey("animation") && tile.getProperties().get("animation", String.class).equals("coin"))
				coinTiles.add((StaticTiledMapTile)tile);
		}
		tiles = map.getTileSets().getTileSet("mapsheet").iterator();
		while (tiles.hasNext()){
			TiledMapTile tile = tiles.next();
			if (tile.getProperties().containsKey("animation") && tile.getProperties().get("animation", String.class).equals("blocco"))
				bloccTiles.add((StaticTiledMapTile)tile);
		}

		//crea i tile animati
		AnimatedTiledMapTile surpriseAnimatedTile = new AnimatedTiledMapTile (1/8f, surpriseTiles);
		for( StaticTiledMapTile framTile: surpriseTiles ){
			surpriseAnimatedTile.getProperties().putAll(framTile.getProperties());
		}
		AnimatedTiledMapTile coinAnimatedTile = new AnimatedTiledMapTile (1/7f, coinTiles);
		for( StaticTiledMapTile framTile: coinTiles ){
			coinAnimatedTile.getProperties().putAll(framTile.getProperties());
		}
		AnimatedTiledMapTile blocAnimatedTile = new AnimatedTiledMapTile( 1/2f, bloccTiles);
		for( StaticTiledMapTile framTile: bloccTiles ){
			blocAnimatedTile.getProperties().putAll(framTile.getProperties());
		}
		TiledMapTileLayer layer = (TiledMapTileLayer) map.getLayers().get("background");

		for(int x = 0; x < layer.getWidth(); x++)
			for(int y = 0; y < layer.getHeight(); y++) {
				Cell cell = layer.getCell(x, y);
				if(cell!=null && cell.getTile().getProperties().containsKey("animation") &&
						cell.getTile().getProperties().get("animation", String.class).equals("surprise"))
					cell.setTile(surpriseAnimatedTile);
				else if (cell!=null && cell.getTile().getProperties().containsKey("animation") &&
						cell.getTile().getProperties().get("animation", String.class).equals("coin"))
					cell.setTile(coinAnimatedTile);
				else if (cell!=null && cell.getTile().getProperties().containsKey("animation") &&
						cell.getTile().getProperties().get("animation", String.class).equals("block"))
					cell.setTile(blocAnimatedTile);		
			}
	}//show

	@Override
	public void hide() {
		dispose();
	}//hide

	@Override
	public void pause() {
		if(isPaused) return;
		isPaused  = true;
		timeAtPause = timer.getTime();
		bgm.pause();
	}//pause

	@Override
	public void resume() {
		if(!isPaused) return;
		isPaused = false;
		timer.setTime(timeAtPause);
		bgm.play();
	}//resume

	@Override
	public void dispose() {
		map.dispose();
		renderer.dispose();
		playerAtlas.dispose();
		bgm.dispose();
	}//dispose

	private void riproduciBGM(){
		bgm = Gdx.audio.newMusic(Gdx.files.internal("com/me/sounds/overworld.mp3"));
		bgm.setLooping(true);
		bgm.play();
	}//riproduciBGM

	//METODI GETTERS
	public static Array<Goomba> getEnemies (){
		return goombas;
	}//getEnemies
	public static Array<OneUP> getOneUP(){
		return funghi;
	}//getOneUp
	public static Array<Mushroom> getMush(){
		return mushes;
	}//getMush
	public static Array<Guscio> getGusci(){
		return gusci;
	}
	public static Array<Koopa> getKoopas() {
		return koopas;
	}
	public static Array<FireFlower> getFireFlower() {
		return fireFlowers;
	}//getFireFlower
	public Music getMusic(){
		return bgm;
	}//getMusic
	public boolean isPaused() {
		return isPaused;
	}//isPaused
	public static Array<Super> getSuper() {
		return supers;
	}

	//METODI SPECIFICI DELLA FIREBALL
	private void inizializzaFuoco(){
		for(int i=0;i<3;i++ )
			fireballs.add(new Fireball ((TiledMapTileLayer)(map.getLayers().get(1)),player));
		System.out.println("inizializzato");
	}//inizializzaFuoco

	public void creaFireball(){
		/*fireball = new Fireball (fireLeft, fireRight, (TiledMapTileLayer)(map.getLayers().get(1)),player);
		fireballs.add(fireball);
		renderer.getSpriteBatch().begin();
		if (player.getSpara() && !fireball.getDeadState() ){
			fireball.draw(renderer.getSpriteBatch());	
		}
		renderer.getSpriteBatch().end();
		fireball.setPosition(player.getX(), player.getY());
		if (player.getVelocity().x > 0){
			fireball.setVelocityX(200 );
		}
		else if (player.getVelocity().x < 0){
			fireball.setVelocityX(-200);
		} else {
			if (player.getsx()){
				fireball.setVelocityX(-200);
			} else{
				fireball.setVelocityX(200 );
			}
		}
		fireNonAncoraDisegnata = true;*/

		System.out.println("Indice fuoco: "+indiceFuoco);
		fireballs.add(new Fireball ((TiledMapTileLayer)(map.getLayers().get(1)),player));
		indiceFuoco = (indiceFuoco+1)%3;
		fireballs.get(indiceFuoco).setPosition(player.getX(), player.getY());
		inizializzaFuoco();
		if( indiceFuoco==2 )
		for(int i=0;i<3;i++){
			fireballs.get(i).setFireDeadState(false);
		}
		if (player.getVelocity().x > 0){
			fireballs.get(indiceFuoco).setVelocityX(200);
		}
		else if (player.getVelocity().x < 0){
			fireballs.get(indiceFuoco).setVelocityX(-200);
		} else {
			if (player.getsx()){
				fireballs.get(indiceFuoco).setVelocityX(-200);
			} else{
				fireballs.get(indiceFuoco).setVelocityX(200);
			}
		}

	}//creaFireball



}//Play
